package excercise;

public class EX05_OOP4 {

	// VO 클래스, Service 클래스 작성법 익히기
	
	public static void main(String[] args) {
		RetangleVO r = new RetangleVO(35, 45, "silver");
		float area = RetangleService.getArea( r.width, r.height );
		System.out.println( area );
		
		//FanVO f = new FanVO( new FanVO().FAST, true, 10, "yellow" );        
		FanVO f = new FanVO( FanVO.FAST, true, 10, "yellow" );
		// System.out.println( 
		//	 FanService.showFanInfo( f.speed, f.on, f.radius, f.color ) );
		System.out.println( FanService.showFanInfo( f ) );
		
		AccountVO a = 
			new AccountVO( 1122, 20000, 4.5F, "20131108" );
		
		AccountService.withdraw( 2500, a.balence );
		System.out.println( a.balence );
		// call by value (값에 의해 전달)
		// 메서드의 매개변수 유형이 기본 자료형인 경우
		// 기본 자료형 값을 메서드의 매개변수로 전달하면
		// JVM은 메서드의 지역변수에 그 값을 복사해 줌
		// 따라서, 메서드의 지역변수 값을 변경하더라도,
		// 전달해준 변수에는 영향을 미치지는 않음
		
		AccountService.withdraw( 2500, a );
		System.out.println( a.balence );
		// call by reference (주소에 의한 전달).
		// 메서드의 매개변수 유형이 참조 자료형인 경우
		// 만일, 참조형 변수를 메서드의 매개변수로 전달하면
		// 지역변수는 참조형 변수가 전달해 준 객체를 가리키게 됨
		// 즉, 참조형 변수에 저장된 값은 실제 값이 아니고
		// 그 값을 가리키는 주소를 의미하기 때문임
		// 따라서, 메서드에서 참조된 객체에 변경을 가하면
		// 그 변화는 호출된 코드에도 반영됨
	}

}

class RetangleVO {
	float width;
	float height;
	String color;
	
	public RetangleVO() {
		width = 1.0F; height = 1.0F; color = "white";
	}
	
	public RetangleVO( float width, float height, String color ) {
		this.width = width;
		this.height = height;
		this.color = color;
	}
}

class RetangleService {
	static float getArea( float width, float height ) { 
		return width * height; 
	}
	static float getPerimter( float width, float height ) { 
		return (2 * width) + (2 * height); 
	}
}

class FanVO {
	// 속도를 나타내는 상수들은
	// 객체 생성없이 바로 사용가능해야 함
	// 따라서, static final 예약어를 사용함
	// 한편, JDK5 이상에서는 이것을 대체하기 위해
	// Enum 이라는 새로운 클래스 자료형이 추가됨
	static final int SLOW = 1;
	static final int MEDIUM = 2;
	static final int FAST = 3;
	
	int speed;
	boolean on;
	float radius;
	String color;
	
	public FanVO() {
		speed = this.SLOW; on = false;
		radius = 5.0F; color = "blue";
	}
	public FanVO( int speed, boolean on,
							float radius, String color ) {
		this.speed = speed; this.on = on;
		this.radius = radius; this.color = color;
	}
	
}

class FanService {
	// 메서드 다중정의overloading
	// 메서드 서명만 다르면 
	// 메서드 이름은 동일하게 작성가능 
	static String showFanInfo( int speed, boolean on, float radius, String color ) {
		String msg = "";
		if ( on )
			msg = speed + "," + color + "," + radius + "," + "작동중";     
		else 
			msg = color + "," + radius + "," + "꺼져있음";
		return msg;	
	}
	
	static String showFanInfo( FanVO f ) {
		String msg = "";
		if ( f.on )
			msg = f.speed + "," + f.color + "," + f.radius + "," + "작동중";     
		else 
			msg = f.color + "," + f.radius + "," + "꺼져있음";
		return msg;	
	}

}

class AccountVO {
	int aid;
	int balence;
	float interestRate;
	String dateCreated;
	
	public AccountVO() { 
		aid = 0; balence = 0; interestRate = 0; 
	}
	public AccountVO( int aid, int balence, 
			float interestRate, String dateCreated ) {
		this.aid = aid; this.balence = balence; 
		this.interestRate = interestRate; 
		this.dateCreated = dateCreated;
	}
	
}

class AccountService {
	static float getMonthlyInterestRate( float interestRate ) {
		return interestRate / 12;
	}
	
	static int withdraw( int z, int x ) {
		z -= x;
		System.out.println( "인출 후 잔액 : " + z );
		return z;
	}
	
	static int withdraw( int gold, AccountVO a ) {
		a.balence -= gold;
		System.out.println( "인출 후 잔액 : " + a.balence );
		return a.balence;
	}
		
	static int deposit( int gold, int balance ) {
		return balance += gold;
	}
}





